மேம்பட்ட TypeScript ஜெனரிக்ஸ் திறப்புகளைத் திறக்கவும்! இந்த வழிகாட்டி keyof ஆப்பரேட்டர் மற்றும் குறியீட்டு அணுகல் வகைகளின் வேறுபாடுகளை, அவற்றை வலுவான, வகை-பாதுகாப்பான உலகளாவிய பயன்பாடுகளுக்கு எவ்வாறு இணைப்பது என்பதை ஆழமாக ஆராய்கிறது.
பொதுவான கட்டுப்பாடுகள் மேம்பட்டது: Keyof ஆப்பரேட்டர் vs. குறியீட்டு அணுகல் வகைகள் விளக்கம்
மென்பொருள் மேம்பாட்டின் பரந்த மற்றும் எப்போதுமே வளர்ந்து வரும் நிலப்பரப்பில், TypeScript ஒரு முக்கியமான கருவியாக உருவெடுத்துள்ளது, இது வலுவான, அளவிடக்கூடிய மற்றும் பராமரிக்கக்கூடிய பயன்பாடுகளை உருவாக்குவதற்கு உதவுகிறது. அதன் நிலையான தட்டச்சு திறன்கள் உலகெங்கிலும் உள்ள டெவலப்பர்களை ஆரம்பத்திலேயே பிழைகளைக் கண்டறியவும், குறியீடு படிக்கும் திறனை மேம்படுத்தவும், பல்வேறு அணிகள் மற்றும் திட்டங்களுக்கு இடையே ஒத்துழைப்பை எளிதாக்கவும் உதவுகிறது. TypeScript இன் சக்தியின் மையத்தில் அதன் அதிநவீன வகை அமைப்பு உள்ளது, குறிப்பாக அதன் ஜெனரிக்ஸ் மற்றும் மேம்பட்ட வகை கையாளுதல் அம்சங்கள். பல டெவலப்பர்கள் அடிப்படை ஜெனரிக்ஸுடன் வசதியாக இருந்தாலும், TypeScript ஐ முழுமையாக தேர்ச்சி பெற, பொதுவான கட்டுப்பாடுகள், keyof ஆப்பரேட்டர் மற்றும் குறியீட்டு அணுகல் வகைகள் போன்ற மேம்பட்ட கருத்துக்களைப் பற்றிய ஆழமான புரிதல் தேவை.
இந்த விரிவான வழிகாட்டி, தங்கள் TypeScript திறன்களை மேம்படுத்த விரும்புவோருக்காக வடிவமைக்கப்பட்டுள்ளது, அடிப்படைகளுக்கு அப்பால் சென்று மொழியின் முழுமையான வெளிப்படுத்தும் சக்தியைப் பயன்படுத்த உதவுகிறது. keyof ஆப்பரேட்டர் மற்றும் குறியீட்டு அணுகல் வகைகளின் நுணுக்கங்களை ஆய்வு செய்து, அவற்றின் தனிப்பட்ட பலங்களை ஆராய்ந்து, ஒவ்வொன்றையும் எப்போது பயன்படுத்த வேண்டும் என்பதைப் புரிந்துகொண்டு, எல்லாவற்றிற்கும் மேலாக, நம்பமுடியாத நெகிழ்வான மற்றும் வகை-பாதுகாப்பான குறியீட்டை உருவாக்க அவற்றை எவ்வாறு இணைப்பது என்பதைக் கண்டறிய ஒரு விரிவான பயணத்தை மேற்கொள்வோம். நீங்கள் ஒரு உலகளாவிய நிறுவன பயன்பாட்டை உருவாக்கினாலும், ஒரு திறந்த மூல நூலகத்தை உருவாக்கினாலும் அல்லது ஒரு பன்முக கலாச்சார மேம்பாட்டுத் திட்டத்திற்குப் பங்களித்தாலும், உயர்தர TypeScript ஐ எழுதுவதற்கு இந்த மேம்பட்ட நுட்பங்கள் அவசியமானவை.
உண்மையான மேம்பட்ட பொதுவான கட்டுப்பாடுகளின் ரகசியங்களைத் திறப்போம் மற்றும் உங்கள் TypeScript மேம்பாட்டை மேம்படுத்துவோம்!
அடிப்படை: TypeScript ஜெனரிக்ஸைப் புரிந்துகொள்வது
keyof மற்றும் குறியீட்டு அணுகல் வகைகளின் குறிப்பிட்ட அம்சங்களை நாம் ஆராய்வதற்கு முன், ஜெனரிக்ஸ் என்ற கருத்தையும் அவை நவீன மென்பொருள் மேம்பாட்டில் ஏன் மிகவும் இன்றியமையாதவை என்பதையும் உறுதியாகப் புரிந்துகொள்வது அவசியம். ஜெனரிக்ஸ் என்பது பலவிதமான தரவு வகைகளுடன் வேலை செய்யக்கூடிய கூறுகளை எழுத உங்களை அனுமதிக்கிறது, ஒரே ஒரு வகைக்குள் கட்டுப்படுத்தப்படாமல். இது நம்பமுடியாத நெகிழ்வுத்தன்மையையும் மறுபயன்பாட்டையும் வழங்குகிறது, இது இன்றைய வேகமான மேம்பாட்டுச் சூழல்களில் மிக முக்கியமானது, குறிப்பாக உலகளாவிய அளவில் பலதரப்பட்ட தரவு கட்டமைப்புகள் மற்றும் வணிக தர்க்கத்தை கையாளும் போது.
அடிப்படை ஜெனரிக்ஸ்: ஒரு நெகிழ்வான அடித்தளம்
ஒரு அணியின் முதல் கூறைத் திரும்பப் பெறும் ஒரு செயல்பாடு உங்களுக்குத் தேவை என்று கற்பனை செய்து பாருங்கள். ஜெனரிக்ஸ் இல்லாமல், நீங்கள் அதை இப்படி எழுதலாம்:
function getFirstElement(arr: any[]): any {
if (arr.length === 0) {
return undefined;
}
return arr[0];
}
// Usage with numbers
const numbers = [1, 2, 3];
const firstNumber = getFirstElement(numbers); // type: any
// Usage with strings
const names = ['Alice', 'Bob'];
const firstName = getFirstElement(names); // type: any
// Problem: We lose type information!
const lengthOfFirstName = (firstName as string).length; // Requires type assertion
இங்கே உள்ள சிக்கல் என்னவென்றால், any வகை பாதுகாப்பை முழுமையாக அழித்துவிடுகிறது. ஜெனரிக்ஸ் இதை தீர்க்கிறது, இது வாதத்தின் வகையைப் பதிவுசெய்து அதைத் திரும்பும் வகையாகப் பயன்படுத்த உங்களை அனுமதிக்கிறது:
function getFirstElement<T>(arr: T[]): T {
if (arr.length === 0) {
// Depending on strict settings, you might need to return T | undefined
// For simplicity, let's assume non-empty arrays or handle undefined explicitly.
// A more robust signature might be T[] => T | undefined.
return undefined as any; // Or handle more carefully
}
return arr[0];
}
const numbers = [1, 2, 3];
const firstNumber = getFirstElement(numbers); // type: number
const names = ['Alice', 'Bob'];
const firstName = getFirstElement(names); // type: string
// Type safety maintained!
const lengthOfFirstName = firstName.length; // No type assertion needed, TypeScript knows it's a string
இங்கே, <T> என்பது T என்ற வகை மாறியை அறிவிக்கிறது. நீங்கள் எண்களின் அணியுடன் getFirstElement ஐ அழைக்கும்போது, T என்பது number ஆகிறது. நீங்கள் சரங்களுடன் அதை அழைக்கும்போது, T என்பது string ஆகிறது. இது ஜெனரிக்ஸின் அடிப்படை சக்தி: பாதுகாப்பை தியாகம் செய்யாமல் வகை ஊகம் மற்றும் மறுபயன்பாடு.
extends உடன் பொதுவான கட்டுப்பாடுகள்
ஜெனரிக்ஸ் மிகுந்த நெகிழ்வுத்தன்மையை வழங்கினாலும், சில சமயங்களில் ஒரு பொதுவான கூறுடன் பயன்படுத்தக்கூடிய வகைகளை நீங்கள் கட்டுப்படுத்த வேண்டும். எடுத்துக்காட்டாக, உங்கள் செயல்பாடு பொதுவான வகை T க்கு எப்போதும் ஒரு குறிப்பிட்ட பண்பு அல்லது முறையைக் கொண்டிருக்க வேண்டும் என்று எதிர்பார்த்தால் என்ன செய்வது? இங்குதான் extends சொல்லைப் பயன்படுத்தி பொதுவான கட்டுப்பாடுகள் நடைமுறைக்கு வருகின்றன.
ஒரு பொருளின் ID ஐ பதிவு செய்யும் ஒரு செயல்பாட்டைக் கருத்தில் கொள்ளுங்கள். எல்லா வகைகளுக்கும் id பண்பு இருக்காது. T க்கு எப்போதும் number (அல்லது string, தேவைகளைப் பொறுத்து) வகையின் id பண்பு இருப்பதை உறுதிப்படுத்த நாம் T ஐ கட்டுப்படுத்த வேண்டும்.
interface HasId {
id: number;
}
function logId<T extends HasId>(item: T): void {
console.log(`ID: ${item.id}`);
}
// Works correctly
logId({ id: 1, name: 'Product A' }); // ID: 1
logId({ id: 2, quantity: 10 }); // ID: 2
// Error: Argument of type '{ name: string; }' is not assignable to parameter of type 'HasId'.
// Property 'id' is missing in type '{ name: string; }' but required in type 'HasId'.
// logId({ name: 'Product B' });
<T extends HasId> ஐப் பயன்படுத்துவதன் மூலம், T ஆனது HasId க்கு ஒதுக்கக்கூடியதாக இருக்க வேண்டும் என்று TypeScript க்கு நாம் கூறுகிறோம். இதன் பொருள் logId க்கு அனுப்பப்படும் எந்தவொரு பொருளும் id: number பண்பைக் கொண்டிருக்க வேண்டும், இது வகை பாதுகாப்பை உறுதிசெய்து இயக்கநேர பிழைகளைத் தடுக்கிறது. ஜெனரிக்ஸ் மற்றும் கட்டுப்பாடுகள் பற்றிய இந்த அடிப்படை புரிதல், நாம் மேம்பட்ட வகை கையாளுதல்களை ஆராயும்போது மிக முக்கியமானது.
ஆழமாக ஆராய்வோம்: keyof ஆப்பரேட்டர்
keyof ஆப்பரேட்டர் என்பது TypeScript இல் ஒரு சக்திவாய்ந்த கருவியாகும், இது ஒரு குறிப்பிட்ட வகையின் அனைத்து பொது பண்புப் பெயர்களையும் (சாவிகள்) ஒரு சர இலக்கிய யூனியன் வகையாக மாற்ற அனுமதிக்கிறது. ஒரு பொருளுக்கான அனைத்து செல்லுபடியாகும் பண்பு அணுகல்களின் பட்டியலை உருவாக்குவது போல இதைக் கருதலாம். தரவு செயலாக்கம், உள்ளமைவு மற்றும் UI மேம்பாடு போன்ற பல்வேறு உலகளாவிய பயன்பாடுகளில், பொருள் பண்புகளில் செயல்படும் மிகவும் நெகிழ்வான ஆனால் வகை-பாதுகாப்பான செயல்பாடுகளை உருவாக்குவதற்கு இது நம்பமுடியாத பயனுள்ளதாக இருக்கும்.
keyof என்ன செய்கிறது
எளிமையாகச் சொன்னால், ஒரு பொருள் வகைக்கு T, keyof T ஆனது T இன் பண்புகளின் பெயர்களைக் குறிக்கும் சர இலக்கிய வகைகளின் ஒரு யூனியனை உருவாக்குகிறது. இது "இந்த வகை பொருளின் பண்புகளை அணுக நான் பயன்படுத்தக்கூடிய அனைத்து சாத்தியமான சாவிகள் யாவை?" என்று கேட்பது போன்றது.
தொடரியல் மற்றும் அடிப்படை பயன்பாடு
தொடரியல் எளிமையானது: keyof TypeName.
interface User {
id: number;
name: string;
email?: string;
age: number;
}
type UserKeys = keyof User; // Type is 'id' | 'name' | 'email' | 'age'
const userKey: UserKeys = 'name'; // Valid
// const invalidKey: UserKeys = 'address'; // Error: Type "address" is not assignable to type 'UserKeys'.
class Product {
public productId: string;
private _cost: number;
protected _warehouseId: string;
constructor(id: string, cost: number) {
this.productId = id;
this._cost = cost;
this._warehouseId = 'default';
}
public getCost(): number {
return this._cost;
}
}
type ProductKeys = keyof Product; // Type is 'productId' | 'getCost'
// Note: private and protected members are not included in keyof for classes,
// as they are not publicly accessible keys.
நீங்கள் பார்ப்பது போல, keyof ஆனது, முறைகள் (செயல்பாடு மதிப்புகளைக் கொண்ட பண்புகள்) உட்பட அனைத்து பொது அணுகல் பண்புப் பெயர்களையும் சரியாக அடையாளம் காட்டுகிறது, ஆனால் தனிப்பட்ட மற்றும் பாதுகாக்கப்பட்ட உறுப்பினர்களை விலக்குகிறது. இந்த நடத்தை அதன் நோக்கத்துடன் ஒத்துப்போகிறது: பண்பு அணுகலுக்கான செல்லுபடியாகும் சாவிகளை அடையாளம் காணுதல்.
keyof பொதுவான கட்டுப்பாடுகளில்
keyof இன் உண்மையான சக்தி பொதுவான கட்டுப்பாடுகளுடன் இணைக்கும்போது வெளிப்படுகிறது. இந்த கலவையானது எந்தவொரு பொருளுடனும் செயல்படக்கூடிய செயல்பாடுகளை எழுத உங்களை அனுமதிக்கிறது, ஆனால் அந்த பொருளில் உண்மையில் இருக்கும் பண்புகளில் மட்டுமே செயல்படும், இது தொகுக்கும்-நேர வகை பாதுகாப்பை உறுதி செய்கிறது.
ஒரு பொதுவான சூழ்நிலையைக் கவனியுங்கள்: ஒரு பொருளில் இருந்து பண்பு மதிப்பை பாதுகாப்பாகப் பெறும் ஒரு பயன்பாட்டுச் செயல்பாடு.
உதாரணம் 1: ஒரு getProperty செயல்பாட்டை உருவாக்குதல்
keyof இல்லாமல், நீங்கள் any ஐ அல்லது குறைவான பாதுகாப்பான அணுகுமுறையைப் பயன்படுத்தலாம்:
function getPropertyUnsafe(obj: any, key: string): any {
return obj[key];
}
const myUser = { id: 1, name: 'Charlie' };
const userName = getPropertyUnsafe(myUser, 'name'); // Returns 'Charlie', but type is any
const userAddress = getPropertyUnsafe(myUser, 'address'); // Returns undefined, no compile-time error
இப்போது, இந்த செயல்பாட்டை வலுவானதாகவும் வகை-பாதுகாப்பானதாகவும் மாற்ற keyof ஐ அறிமுகப்படுத்துவோம்:
/**
* Safely retrieves a property from an object.
* @template T The type of the object.
* @template K The type of the key, constrained to be a key of T.
* @param obj The object to query.
* @param key The key (property name) to retrieve.
* @returns The value of the property at the given key.
*/
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
interface Employee {
employeeId: number;
firstName: string;
lastName: string;
department: string;
}
const employee: Employee = {
employeeId: 101,
firstName: 'Anna',
lastName: 'Johnson',
department: 'Engineering'
};
// Valid usage:
const empFirstName = getProperty(employee, 'firstName'); // type: string, value: 'Anna'
console.log(`Employee First Name: ${empFirstName}`);
const empId = getProperty(employee, 'employeeId'); // type: number, value: 101
console.log(`Employee ID: ${empId}`);
// Invalid usage (compile-time error):
// Argument of type "salary" is not assignable to parameter of type "employeeId" | "firstName" | "lastName" | "department".
// const empSalary = getProperty(employee, 'salary');
interface Configuration {
locale: 'en-US' | 'es-ES' | 'fr-FR';
theme: 'light' | 'dark';
maxItemsPerPage: number;
}
const appConfig: Configuration = {
locale: 'en-US',
theme: 'dark',
maxItemsPerPage: 20
};
const currentTheme = getProperty(appConfig, 'theme'); // type: 'light' | 'dark', value: 'dark'
console.log(`Current Theme: ${currentTheme}`);
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] ஐப் பிரித்துப் பார்ப்போம்:
<T>: பொருளுக்கான ஒரு பொதுவான வகை அளவுருTஐ அறிவிக்கிறது.<K extends keyof T>: கீக்கான ஒரு பொதுவான வகை அளவுருKஐ அறிவிக்கிறது. இது முக்கியமான பகுதி. இதுKஐTஇன் ஒரு கீயைக் குறிக்கும் சர இலக்கிய வகைகளில் ஒன்றாகக் கட்டுப்படுத்துகிறது. எனவே,Tஎன்பதுEmployeeஆக இருந்தால்,Kஎன்பது'employeeId' | 'firstName' | 'lastName' | 'department'ஆக இருக்க வேண்டும்.(obj: T, key: K): செயல்பாட்டு அளவுருக்கள்.objஎன்பதுTவகையைச் சேர்ந்தது, மற்றும்keyஎன்பதுKவகையைச் சேர்ந்தது.: T[K]: இது ஒரு குறியீட்டு அணுகல் வகை (இதை அடுத்து விரிவாகப் பார்ப்போம்), இது திரும்பும் வகையை குறிப்பிட இங்கு பயன்படுத்தப்படுகிறது. இதன் பொருள் "Tஎன்ற பொருள் வகைக்குள்Kகீயில் உள்ள பண்பின் வகை".Tஎன்பதுEmployeeஆகவும்Kஎன்பது'firstName'ஆகவும் இருந்தால்,T[K]ஆனதுstringஆக மாறுகிறது.Kஎன்பது'employeeId'ஆக இருந்தால், அதுnumberஆக மாறுகிறது.
keyof கட்டுப்பாடுகளின் நன்மைகள்
- தொகுக்கும்-நேர பாதுகாப்பு: இல்லாத பண்புகளை அணுகுவதைத் தடுக்கிறது, இயக்கநேர பிழைகளைக் குறைக்கிறது.
- மேம்பட்ட டெவலப்பர் அனுபவம்: செயல்பாட்டை அழைக்கும்போது சாவிகளுக்கு புத்திசாலித்தனமான தானியங்கு நிறைவு பரிந்துரைகளை வழங்குகிறது.
- மேம்பட்ட படிக்கும் திறன்: வகை கையொப்பம், கீ ஆனது பொருளுக்கு சொந்தமானதாக இருக்க வேண்டும் என்பதை தெளிவாகத் தெரிவிக்கிறது.
- வலுவான மறுசீரமைப்பு: நீங்கள்
Employeeஇல் ஒரு பண்பின் பெயரை மாற்றினால், TypeScript உடனடியாகக் கொடியிடும் அழைப்புகளைப் பயன்படுத்தும்getPropertyபழைய கீயைப் பயன்படுத்தி.
மேம்பட்ட keyof சூழ்நிலைகள்
சாவிகள் மீது மீண்டும் மீண்டும் செயல்படுதல்
keyof என்பது ஒரு வகை ஆப்பரேட்டராக இருந்தாலும், நீங்கள் பொருள் சாவிகள் மீது மீண்டும் மீண்டும் செயல்படும் செயல்பாடுகளை எவ்வாறு வடிவமைக்கலாம் என்பதை இது அடிக்கடி தெரிவிக்கிறது, நீங்கள் பயன்படுத்தும் சாவிகள் எப்போதும் செல்லுபடியாகும் என்பதை உறுதிப்படுத்துகிறது.
function logAllProperties<T extends object>(obj: T): void {
// Here, Object.keys returns string[], not keyof T, so we often need assertions
// or to be careful. However, keyof T guides our thinking for type safety.
(Object.keys(obj) as Array<keyof T>).forEach(key => {
// We know 'key' is a valid key for 'obj'
console.log(`${String(key)}: ${obj[key]}`);
});
}
interface MenuItem {
id: string;
label: string;
price: number;
available: boolean;
}
const coffee: MenuItem = {
id: 'cappuccino',
label: 'Cappuccino',
price: 4.50,
available: true
};
logAllProperties(coffee);
// Output:
// id: cappuccino
// label: Cappuccino
// price: 4.5
// available: true
இந்த எடுத்துக்காட்டில், keyof T என்பது Object.keys ஆனது ஒரு முழுமையான வகை-பாதுகாப்பான உலகில் *என்ன* திரும்பப் பெற வேண்டும் என்பதற்கான கருத்தியல் வழிகாட்டும் கொள்கையாக செயல்படுகிறது. Object.keys ஆனது TypeScript இன் தொகுக்கும்-நேர வகை அமைப்பை விட இயக்கநேரத்தில் இயல்பாகவே குறைவான வகை-அறிவைக் கொண்டிருப்பதால், நமக்கு அடிக்கடி as Array<keyof T> என்ற வகை உறுதிப்படுத்தல் தேவைப்படுகிறது. இது இயக்கநேர JavaScript மற்றும் தொகுக்கும்-நேர TypeScript க்கு இடையிலான தொடர்பை எடுத்துக்காட்டுகிறது.
யூனியன் வகைகளுடன் keyof
நீங்கள் ஒரு யூனியன் வகைக்கு keyof ஐப் பயன்படுத்தும்போது, அது யூனியனில் உள்ள அனைத்து வகைகளின் சாவிகளின் குறுக்கீட்டைத் திரும்பப் பெறுகிறது. இதன் பொருள், யூனியனில் உள்ள அனைத்து உறுப்பினர்களுக்கும் பொதுவான சாவிகளை மட்டுமே இது உள்ளடக்கும்.
interface Apple {
color: string;
sweetness: number;
}
interface Orange {
color: string;
citrus: boolean;
}
type Fruit = Apple | Orange;
type FruitKeys = keyof Fruit; // Type is 'color'
// 'sweetness' is only in Apple, 'citrus' is only in Orange.
// 'color' is common to both.
இந்த நடத்தை நினைவில் கொள்வது முக்கியம், ஏனெனில் FruitKeys இலிருந்து தேர்ந்தெடுக்கப்பட்ட எந்தவொரு சாவியும் Fruit வகையின் எந்தவொரு பொருளிலும் (அது Apple ஆக இருந்தாலும் அல்லது Orange ஆக இருந்தாலும்) எப்போதும் ஒரு செல்லுபடியாகும் பண்பாக இருக்கும் என்பதை இது உறுதி செய்கிறது. இது பல்லுருவ தரவு கட்டமைப்புகளுடன் பணிபுரியும் போது இயக்கநேர பிழைகளைத் தடுக்கிறது.
typeof உடன் keyof
ஒரு பொருளின் வகையிலிருந்து அதன் மதிப்பிலிருந்து நேரடியாக சாவிகளைப் பிரித்தெடுக்க keyof ஐ typeof உடன் இணைத்து பயன்படுத்தலாம், இது உள்ளமைவு பொருள்கள் அல்லது மாறிலிகளுக்கு குறிப்பாக பயனுள்ளதாக இருக்கும்.
const APP_SETTINGS = {
API_URL: 'https://api.example.com',
TIMEOUT_MS: 5000,
DEBUG_MODE: false
};
type AppSettingKeys = keyof typeof APP_SETTINGS; // Type is 'API_URL' | 'TIMEOUT_MS' | 'DEBUG_MODE'
function getAppSetting<K extends AppSettingKeys>(key: K): (typeof APP_SETTINGS)[K] {
return APP_SETTINGS[key];
}
const apiUrl = getAppSetting('API_URL'); // type: string
const debugMode = getAppSetting('DEBUG_MODE'); // type: boolean
// const invalidSetting = getAppSetting('LOG_LEVEL'); // Error
உலகளாவிய உள்ளமைவு பொருள்களுடன் தொடர்பு கொள்ளும்போது வகை பாதுகாப்பை பராமரிக்க இந்த முறை மிகவும் பயனுள்ளதாக இருக்கும், பல்வேறு தொகுதிகள் மற்றும் அணிகள் முழுவதும் நிலைத்தன்மையை உறுதி செய்கிறது, குறிப்பாக பல்வேறு பங்களிப்பாளர்களுடன் பெரிய அளவிலான திட்டங்களில் இது மதிப்புமிக்கது.
குறியீட்டு அணுகல் வகைகளை (தேடல் வகைகள்) வெளிப்படுத்துதல்
keyof உங்களுக்கு பண்புகளின் பெயர்களைக் கொடுத்தாலும், ஒரு குறியீட்டு அணுகல் வகை (பொதுவாக தேடல் வகை என்றும் குறிப்பிடப்படுகிறது) மற்றொரு வகையிலிருந்து ஒரு குறிப்பிட்ட பண்பின் வகையை பிரித்தெடுக்க உங்களை அனுமதிக்கிறது. இது "இந்த பொருள் வகைக்குள் இந்த குறிப்பிட்ட கீயில் உள்ள மதிப்பின் வகை என்ன?" என்று கேட்பது போன்றது. ஏற்கனவே உள்ள வகைகளிலிருந்து பெறப்பட்ட வகைகளை உருவாக்குவதற்கும், மறுபயன்பாட்டை மேம்படுத்துவதற்கும் மற்றும் உங்கள் வகை வரையறைகளில் உள்ள தேவையற்ற தன்மையைக் குறைப்பதற்கும் இந்த திறன் அடிப்படையானது.
குறியீட்டு அணுகல் வகைகள் என்ன செய்கின்றன
ஒரு குறியீட்டு அணுகல் வகை, பண்பு கீயுடன் தொடர்புடைய வகையைத் தேட, வகை மட்டத்தில் பிராக்கெட் குறியீட்டை (JavaScript இல் பண்புகளை அணுகுவது போல) பயன்படுத்துகிறது. மற்ற வகைகளின் கட்டமைப்பின் அடிப்படையில் வகைகளை மாறும் விதமாக உருவாக்குவதற்கு இது மிக முக்கியமானது.
தொடரியல் மற்றும் அடிப்படை பயன்பாடு
தொடரியல் TypeName[KeyType], இங்கு KeyType என்பது பொதுவாக ஒரு சர இலக்கிய வகை அல்லது TypeName இன் செல்லுபடியாகும் சாவிகளுக்கு ஒத்த சர இலக்கிய வகைகளின் ஒரு யூனியன்.
interface ProductInfo {
name: string;
price: number;
category: 'Electronics' | 'Apparel' | 'Books';
details: { weight: string; dimensions: string };
}
type ProductNameType = ProductInfo['name']; // Type is string
type ProductPriceType = ProductInfo['price']; // Type is number
type ProductCategoryType = ProductInfo['category']; // Type is 'Electronics' | 'Apparel' | 'Books'
type ProductDetailsType = ProductInfo['details']; // Type is { weight: string; dimensions: string; }
// You can also use a union of keys:
type NameAndPrice = ProductInfo['name' | 'price']; // Type is string | number
// If a key doesn't exist, it's a compile-time error:
// type InvalidType = ProductInfo['nonExistentKey']; // Error: Property 'nonExistentKey' does not exist on type 'ProductInfo'.
ஒரு குறிப்பிட்ட பண்பின் வகையையோ, அல்லது பல பண்புகளுக்கான வகைகளின் யூனியனையோ, ஏற்கனவே உள்ள ஒரு இடைமுகம் அல்லது வகை மாற்றியமைப்பிலிருந்து துல்லியமாகப் பிரித்தெடுக்க குறியீட்டு அணுகல் வகைகள் எவ்வாறு அனுமதிக்கின்றன என்பதை இது காட்டுகிறது. ஒரு பெரிய பயன்பாட்டின் வெவ்வேறு பகுதிகளில், குறிப்பாக பயன்பாட்டின் சில பகுதிகள் வெவ்வேறு அணிகளால் அல்லது வெவ்வேறு புவியியல் இருப்பிடங்களில் உருவாக்கப்படும் போது, வகை நிலைத்தன்மையை உறுதி செய்வதற்கு இது மிகவும் மதிப்புமிக்கது.
பொதுவான சூழல்களில் குறியீட்டு அணுகல் வகைகள்
keyof ஐப் போலவே, குறியீட்டு அணுகல் வகைகளும் பொதுவான வரையறைகளுக்குள் பயன்படுத்தப்படும்போது கணிசமான சக்தியைப் பெறுகின்றன. உள்ளீடு பொதுவான வகை மற்றும் ஒரு கீயின் அடிப்படையில் ஒரு பொதுவான செயல்பாடு அல்லது பயன்பாட்டு வகையின் திரும்பும் வகையையோ அல்லது அளவுரு வகையையோ மாறும் விதமாக தீர்மானிக்க அவை உங்களை அனுமதிக்கின்றன.
உதாரணம் 2: திரும்பும் வகையில் குறியீட்டு அணுகலுடன் மறுபரிசீலனை செய்யப்பட்ட getProperty செயல்பாடு
எங்கள் getProperty செயல்பாட்டில் இதை நாம் ஏற்கனவே பார்த்தோம், ஆனால் T[K] இன் பங்கை மீண்டும் வலியுறுத்தி வலியுறுத்துவோம்:
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
interface Customer {
id: string;
firstName: string;
lastName: string;
preferences: { email: boolean; sms: boolean };
}
const customer: Customer = {
id: 'cust-123',
firstName: 'Maria',
lastName: 'Gonzales',
preferences: { email: true, sms: false }
};
const customerFirstName = getProperty(customer, 'firstName'); // Type: string, Value: 'Maria'
const customerPreferences = getProperty(customer, 'preferences'); // Type: { email: boolean; sms: boolean; }, Value: { email: true, sms: false }
// You can even access nested properties, but the getProperty function itself
// only works for top-level keys. For nested access, you'd need a more complex generic.
// For example, to get customer.preferences.email, you'd chain calls or use a different utility.
// const customerEmailPref = getProperty(customer.preferences, 'email'); // Type: boolean, Value: true
இங்கே, T[K] என்பது மிக முக்கியமானது. getProperty இன் திரும்பும் வகை T என்ற பொருளில் உள்ள K என்ற பண்பின் வகையாக இருக்க வேண்டும் என்று இது TypeScript க்கு சொல்கிறது. கொடுக்கப்பட்ட குறிப்பிட்ட கீயின் அடிப்படையில் அதன் திரும்பும் வகையை மாற்றியமைத்து, இந்த செயல்பாட்டை மிகவும் வகை-பாதுகாப்பானதாகவும் பல்துறை சார்ந்ததாகவும் மாற்றுவது இதுதான்.
ஒரு குறிப்பிட்ட பண்பின் வகையைப் பிரித்தெடுத்தல்
குறியீட்டு அணுகல் வகைகள் செயல்பாட்டு திரும்பும் வகைகளுக்கு மட்டும் அல்ல. ஏற்கனவே உள்ள வகைகளின் பகுதிகளை அடிப்படையாகக் கொண்டு புதிய வகைகளை வரையறுப்பதற்கு அவை நம்பமுடியாத அளவிற்கு பயனுள்ளதாக இருக்கும். குறிப்பிட்ட பண்புகளை மட்டும் கொண்ட ஒரு புதிய பொருளை உருவாக்க வேண்டிய சூழ்நிலைகளில் அல்லது பெரிய தரவு மாதிரியிலிருந்து தரவின் ஒரு துணைக்குழுவை மட்டுமே காட்டும் UI கூறுக்கான வகையை வரையறுக்கும் போது இது பொதுவானது.
interface FinancialReport {
reportId: string;
dateGenerated: Date;
totalRevenue: number;
expenses: number;
profit: number;
currency: 'USD' | 'EUR' | 'JPY';
}
type EssentialReportInfo = {
reportId: FinancialReport['reportId'];
date: FinancialReport['dateGenerated'];
currency: FinancialReport['currency'];
};
const summary: EssentialReportInfo = {
reportId: 'FR-2023-Q4',
date: new Date(),
currency: 'EUR' // This is type-checked correctly
};
// We can also create a type for a property's value using a type alias:
type CurrencyType = FinancialReport['currency']; // Type is 'USD' | 'EUR' | 'JPY'
function formatAmount(amount: number, currency: CurrencyType): string {
return `${amount.toFixed(2)} ${currency}`;
}
console.log(formatAmount(1234.56, 'USD')); // 1234.56 USD
// console.log(formatAmount(789.00, 'GBP')); // Error: Type "GBP" is not assignable to type 'CurrencyType'.
குறியீட்டு அணுகல் வகைகள் எவ்வாறு புதிய வகைகளை உருவாக்க அல்லது அளவுருக்களின் எதிர்பார்க்கப்படும் வகையை வரையறுக்கப் பயன்படுத்தப்படலாம் என்பதை இது காட்டுகிறது, உங்கள் அமைப்பின் வெவ்வேறு பகுதிகள் சீரான வரையறைகளுக்கு இணங்குவதை உறுதிசெய்கிறது, இது பெரிய, விநியோகிக்கப்பட்ட மேம்பாட்டுக் குழுக்களுக்கு மிக முக்கியமானது.
மேம்பட்ட குறியீட்டு அணுகல் வகை சூழ்நிலைகள்
யூனியன் வகைகளுடன் குறியீட்டு அணுகல்
குறியீட்டு அணுகல் வகையில் ஒரு இலக்கிய வகைகளின் யூனியனை கீயாகப் பயன்படுத்தும்போது, யூனியனில் உள்ள ஒவ்வொரு கீக்கும் ஒத்த பண்பு வகைகளின் யூனியனை TypeScript திரும்பப் பெறுகிறது.
interface EventData {
type: 'click' | 'submit' | 'scroll';
timestamp: number;
userId: string;
target?: HTMLElement;
value?: string;
}
type EventIdentifiers = EventData['type' | 'userId']; // Type is 'click' | 'submit' | 'scroll' | string
// Because 'type' is a union of string literals, and 'userId' is a string,
// the resulting type is 'click' | 'submit' | 'scroll' | string, which simplifies to string.
// Let's refine for a more illustrative example:
interface Book {
title: string;
author: string;
pages: number;
isAvailable: boolean;
}
type BookStringOrNumberProps = Book['title' | 'author' | 'pages']; // Type is string | number
// 'title' is string, 'author' is string, 'pages' is number.
// The union of these is string | number.
இது "இந்த குறிப்பிட்ட பண்புகளில் ஏதேனும் ஒன்று" என்பதைக் குறிக்கும் வகைகளை உருவாக்குவதற்கான ஒரு சக்திவாய்ந்த வழியாகும், இது நெகிழ்வான தரவு இடைமுகங்களைக் கையாளும் போது அல்லது பொதுவான தரவு-பிணைப்பு வழிமுறைகளைச் செயல்படுத்தும் போது பயனுள்ளதாக இருக்கும்.
நிபந்தனை வகைகள் மற்றும் குறியீட்டு அணுகல்
குறியீட்டு அணுகல் வகைகள் அடிக்கடி நிபந்தனை வகைகளுடன் இணைந்து மிகவும் மாறும் மற்றும் தழுவல் வகை மாற்றங்களை உருவாக்குகின்றன. நிபந்தனை வகைகள் ஒரு நிபந்தனையின் அடிப்படையில் ஒரு வகையைத் தேர்ந்தெடுக்க உங்களை அனுமதிக்கின்றன.
interface Device {
id: string;
name: string;
firmwareVersion: string;
lastPing: Date;
isOnline: boolean;
}
// Type that extracts only string properties from a given object type T
type StringProperties<T> = {
[K in keyof T]: T[K] extends string ? K : never;
}[keyof T];
type DeviceStringKeys = StringProperties<Device>; // Type is 'id' | 'name' | 'firmwareVersion'
// This creates a new type that contains only the string properties of Device
type DeviceStringsOnly = Pick<Device, DeviceStringKeys>;
/*
Equivalent to:
interface DeviceStringsOnly {
id: string;
name: string;
firmwareVersion: string;
}
*/
const myDeviceStrings: DeviceStringsOnly = {
id: 'dev-001',
name: 'Sensor Unit Alpha',
firmwareVersion: '1.2.3'
};
// myDeviceStrings.isOnline; // Error: Property 'isOnline' does not exist on type 'DeviceStringsOnly'.
இந்த மேம்பட்ட முறை, keyof (K in keyof T இல்) மற்றும் குறியீட்டு அணுகல் வகைகள் (T[K]) நிபந்தனை வகைகளுடன் (extends string ? K : never) இணைந்து அதிநவீன வகை வடிகட்டுதல் மற்றும் மாற்றத்தைச் செய்ய எவ்வாறு செயல்படுகின்றன என்பதைக் காட்டுகிறது. இந்த வகையான மேம்பட்ட வகை கையாளுதல் மிகவும் தழுவல் மற்றும் வெளிப்படுத்தும் API கள் மற்றும் பயன்பாட்டு நூலகங்களை உருவாக்குவதற்கு விலைமதிப்பற்றது.
keyof ஆப்பரேட்டர் vs. குறியீட்டு அணுகல் வகைகள்: ஒரு நேரடி ஒப்பீடு
இந்த நேரத்தில், keyof மற்றும் குறியீட்டு அணுகல் வகைகளின் தனித்துவமான பங்கை நீங்கள் ஆச்சரியப்படலாம், மேலும் ஒவ்வொன்றையும் எப்போது பயன்படுத்த வேண்டும் என்றும் நீங்கள் யோசிக்கலாம். அவை பெரும்பாலும் ஒன்றாகத் தோன்றினாலும், அவற்றின் அடிப்படை நோக்கங்கள் வேறுபட்டவை ஆனால் ஒன்றுக்கொன்று நிரப்புபவை.
அவை என்ன திரும்பப் பெறுகின்றன
keyof T:Tஇன் பண்புகளின் பெயர்களைக் குறிக்கும் சர இலக்கிய வகைகளின் யூனியனை திரும்பப் பெறுகிறது. இது பண்புகளின் "லேபிள்கள்" அல்லது "அடையாளங்காட்டிகள்" ஐ உங்களுக்கு வழங்குகிறது.T[K](குறியீட்டு அணுகல் வகை):Tவகைக்குள்Kகீயுடன் தொடர்புடைய மதிப்பின் வகையை திரும்பப் பெறுகிறது. இது ஒரு குறிப்பிட்ட லேபிளில் உள்ள "உள்ளடக்க வகையை" உங்களுக்கு வழங்குகிறது.
ஒவ்வொன்றையும் எப்போது பயன்படுத்த வேண்டும்
keyofஐ நீங்கள் பயன்படுத்த வேண்டியிருக்கும் போது:- ஒரு பொதுவான வகை அளவுருவை மற்றொரு வகையின் செல்லுபடியாகும் பண்புப் பெயராகக் கட்டுப்படுத்த (எ.கா.,
K extends keyof T). - ஒரு குறிப்பிட்ட வகையின் சாத்தியமான அனைத்து பண்புப் பெயர்களையும் பட்டியலிட.
Pick,Omit, அல்லது தனிப்பயன் மேப்பிங் வகைகள் போன்ற சாவிகள் மீது மீண்டும் செயல்படும் பயன்பாட்டு வகைகளை உருவாக்க.
- ஒரு பொதுவான வகை அளவுருவை மற்றொரு வகையின் செல்லுபடியாகும் பண்புப் பெயராகக் கட்டுப்படுத்த (எ.கா.,
- குறியீட்டு அணுகல் வகைகளை (
T[K]) நீங்கள் பயன்படுத்த வேண்டியிருக்கும் போது:- ஒரு பொருள் வகையிலிருந்து ஒரு பண்பின் குறிப்பிட்ட வகையை மீட்டெடுக்க.
- ஒரு பொருள் மற்றும் ஒரு கீயின் அடிப்படையில் ஒரு செயல்பாட்டின் திரும்பும் வகையை மாறும் விதமாக தீர்மானிக்க (எ.கா.,
getProperty's திரும்பும் வகை). - ஒரு பொருள் மற்றும் ஒரு கீயின் அடிப்படையில் ஒரு செயல்பாட்டின் திரும்பும் வகையை மாறும் விதமாக தீர்மானிக்க (எ.கா.,
getPropertyஇன் திரும்பும் வகை). - வகை-மட்ட தேடல்களைச் செய்ய.
வேறுபாடு நுட்பமானது ஆனால் முக்கியமானது: keyof என்பது *சாவிகளைப்* பற்றியது, அதே சமயம் குறியீட்டு அணுகல் வகைகள் அந்த சாவிகளில் உள்ள *மதிப்புகளின் வகைகளைப்* பற்றியது.
ஒத்திசைந்த சக்தி: keyof மற்றும் குறியீட்டு அணுகல் வகைகளை ஒன்றாகப் பயன்படுத்துதல்
இந்தக் கருத்துகளின் மிகவும் சக்திவாய்ந்த பயன்பாடுகள் பெரும்பாலும் அவற்றை இணைப்பதே ஆகும். சிறந்த எடுத்துக்காட்டு எங்கள் getProperty செயல்பாடு:
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
இந்த கையொப்பத்தை மீண்டும் பிரித்துப் பார்ப்போம், ஒத்திசைவை பாராட்டுவோம்:
<T>: பொருளுக்கான ஒரு பொதுவான வகைTஐ நாம் அறிமுகப்படுத்துகிறோம். இது செயல்பாடு *எந்தவொரு* பொருள் வகையுடனும் செயல்பட அனுமதிக்கிறது.<K extends keyof T>: பண்பு கீக்கான இரண்டாவது பொதுவான வகைKஐ நாம் அறிமுகப்படுத்துகிறோம்.extends keyof Tகட்டுப்பாடு மிக முக்கியமானது; இது செயல்பாட்டிற்கு அனுப்பப்படும்keyஆர்குமென்ட் ஆனதுobjஇன் செல்லுபடியாகும் பண்புப் பெயராக இருக்க வேண்டும் என்பதை உறுதி செய்கிறது. இங்குkeyofஇல்லாமல்,Kஎந்த சரமாகவும் இருக்கலாம், இது செயல்பாட்டை பாதுகாப்பற்றதாக மாற்றும்.(obj: T, key: K): செயல்பாட்டின் அளவுருக்கள்Tமற்றும்Kவகைகள்.: T[K]: இது குறியீட்டு அணுகல் வகை. இது திரும்பும் வகையை மாறும் விதமாக தீர்மானிக்கிறது. ஏனெனில்KஆனதுTஇன் ஒரு கீயாக கட்டுப்படுத்தப்பட்டுள்ளது,T[K]அந்த குறிப்பிட்ட பண்பின் மதிப்பின் வகையை துல்லியமாக நமக்கு வழங்குகிறது. இது திரும்பும் மதிப்பிற்கான வலுவான வகை ஊகத்தை வழங்குகிறது.T[K]இல்லாமல், திரும்பும் வகைanyஅல்லது ஒரு பரந்த வகையாக இருக்கும், குறிப்பிட்ட தன்மையை இழக்கும்.
மிகவும் சிக்கலான பயன்பாட்டு வகைகளை உருவாக்குதல்
TypeScript இன் பல உள்ளமைக்கப்பட்ட பயன்பாட்டு வகைகள், அதாவது Pick<T, K> மற்றும் Omit<T, K>, உள்நாட்டில் keyof மற்றும் குறியீட்டு அணுகல் வகைகளைப் பயன்படுத்துகின்றன. Pick இன் எளிமைப்படுத்தப்பட்ட பதிப்பை நீங்கள் எவ்வாறு செயல்படுத்தலாம் என்பதைப் பார்ப்போம்:
/**
* Constructs a type by picking the set of properties K from Type T.
* @template T The original type.
* @template K The union of keys to pick, which must be keys of T.
*/
type MyPick<T, K extends keyof T> = {
[P in K]: T[P];
};
interface ServerLog {
id: string;
timestamp: Date;
level: 'info' | 'warn' | 'error';
message: string;
sourceIp: string;
userId?: string;
}
type CriticalLogInfo = MyPick<ServerLog, 'id' | 'timestamp' | 'level' | 'message'>;
/*
Equivalent to:
interface CriticalLogInfo {
id: string;
timestamp: Date;
level: 'info' | 'warn' | 'error';
message: string;
}
*/
const errorLog: CriticalLogInfo = {
id: 'log-001',
timestamp: new Date(),
level: 'error',
message: 'Database connection failed'
};
// errorLog.sourceIp; // Error: Property 'sourceIp' does not exist on type 'CriticalLogInfo'.
MyPick<T, K extends keyof T> இல்:
K extends keyof T: நாம் தேர்ந்தெடுக்க விரும்பும் சாவிகள் (K) அசல் வகைTஇன் செல்லுபடியாகும் சாவிகள் என்பதை உறுதி செய்கிறது.[P in K]: இது ஒரு மேப் செய்யப்பட்ட வகை. இது யூனியன் வகைKஇல் உள்ள ஒவ்வொரு இலக்கிய வகைPமீதும் மீண்டும் செயல்படுகிறது.T[P]: ஒவ்வொரு கீPக்கும், இது அசல் வகைTஇலிருந்து தொடர்புடைய பண்பின் வகையைப் பெற ஒரு குறியீட்டு அணுகல் வகையைப் பயன்படுத்துகிறது.
ஏற்கனவே உள்ள வகைகளின் பகுதிகளை துல்லியமாகத் தேர்ந்தெடுத்து பிரித்தெடுப்பதன் மூலம் புதிய, வகை-பாதுகாப்பான கட்டமைப்புகளை உருவாக்க இது எவ்வாறு சாத்தியமாக்குகிறது என்பதை இந்த எடுத்துக்காட்டு அழகாக விளக்குகிறது. அத்தகைய பயன்பாட்டு வகைகள் சிக்கலான அமைப்புகள் முழுவதும் தரவு நிலைத்தன்மையை பராமரிப்பதற்கு விலைமதிப்பற்றவை, குறிப்பாக வெவ்வேறு கூறுகள் (எ.கா., ஒரு முன்முனை UI, ஒரு பின்னணி சேவை, ஒரு மொபைல் பயன்பாடு) ஒரு பகிரப்பட்ட தரவு மாதிரியின் மாறுபட்ட துணைக்குழுக்களுடன் தொடர்பு கொள்ளும் போது.
மாறும் விதமாக `Record` வகைகளை உருவாக்குதல்
Record<K, T> பயன்பாட்டு வகை மற்றொரு சக்திவாய்ந்த உள்ளமைந்த வகையாகும், இது ஒரு பொருள் வகையை உருவாக்குகிறது, அதன் பண்பு சாவிகள் K வகையைச் சேர்ந்தவை மற்றும் அதன் பண்பு மதிப்புகள் T வகையைச் சேர்ந்தவை. ஏற்கனவே உள்ள வகையிலிருந்து சாவிகள் பெறப்பட்ட அகராதிகள் அல்லது வரைபடங்களுக்கான வகைகளை மாறும் விதமாக உருவாக்க keyof ஐ Record உடன் இணைக்கலாம்.
interface Permissions {
read: boolean;
write: boolean;
execute: boolean;
admin: boolean;
}
// Create a type that maps each permission key to a 'PermissionStatus'
type PermissionStatus = 'granted' | 'denied' | 'pending';
type PermissionsMapping = Record<keyof Permissions, PermissionStatus>;
/*
Equivalent to:
{
read: 'granted' | 'denied' | 'pending';
write: 'granted' | 'denied' | 'pending';
execute: 'granted' | 'denied' | 'pending';
admin: 'granted' | 'denied' | 'pending';
}
*/
const userPermissions: PermissionsMapping = {
read: 'granted',
write: 'denied',
execute: 'pending',
admin: 'denied'
};
// userPermissions.delete = 'granted'; // Error: Property 'delete' does not exist on type 'PermissionsMapping'.
சாவிகள் நேரடியாக தற்போதுள்ள தரவு மாதிரி பண்புகள் அல்லது செயல்பாட்டு திறன்களுடன் இணைக்கப்பட்ட தேடல் அட்டவணைகள், நிலை டாஷ்போர்டுகள் அல்லது அணுகல் கட்டுப்பாட்டு பட்டியல்களை உருவாக்குவதற்கு இந்த முறை மிகவும் பயனுள்ளதாக இருக்கும்.
keyof மற்றும் குறியீட்டு அணுகலுடன் வகைகளை மேப்பிங் செய்தல்
மேப்பிங் வகைகள் ஏற்கனவே உள்ள வகையின் ஒவ்வொரு பண்பையும் ஒரு புதிய வகையாக மாற்ற உங்களை அனுமதிக்கின்றன. இங்குதான் keyof மற்றும் குறியீட்டு அணுகல் வகைகள் உண்மையாக ஜொலிக்கின்றன, சிக்கலான வகை வழித்தோன்றல்களை செயல்படுத்துகின்றன. ஒரு பொதுவான பயன்பாட்டு வழக்கு என்பது ஒரு பொருளின் அனைத்து பண்புகளையும் ஒத்திசைவற்ற செயல்பாடுகளாக மாற்றுவதாகும், இது API வடிவமைப்பு அல்லது நிகழ்வு-உந்தப்பட்ட கட்டமைப்புகளில் ஒரு பொதுவான முறையைக் குறிக்கிறது.
உதாரணம்: `MapToPromises<T>`
ஒரு பொருள் வகையை T எடுத்து, ஒவ்வொரு பண்பின் மதிப்பும் ஒரு Promise இல் மூடப்பட்ட ஒரு புதிய வகையாக மாற்றும் ஒரு பயன்பாட்டு வகையை உருவாக்குவோம்.
/**
* Transforms an object type T into a new type where each property's value
* is wrapped in a Promise.
* @template T The original object type.
*/
type MapToPromises<T> = {
[P in keyof T]: Promise<T[P]>;
};
interface UserData {
id: string;
username: string;
email: string;
age: number;
}
type AsyncUserData = MapToPromises<UserData>;
/*
Equivalent to:
interface AsyncUserData {
id: Promise<string>;
username: Promise<string>;
email: Promise<string>;
age: Promise<number>;
}
*/
// Example usage:
async function fetchUserData(): Promise<AsyncUserData> {
return {
id: Promise.resolve('user-abc'),
username: Promise.resolve('global_dev'),
email: Promise.resolve('global.dev@example.com'),
age: Promise.resolve(30)
};
}
async function displayUser() {
const data = await fetchUserData();
const username = await data.username;
console.log(`Fetched Username: ${username}`); // Fetched Username: global_dev
const email = await data.email;
// console.log(email.toUpperCase()); // This would be type-safe (string methods available)
}
displayUser();
MapToPromises<T> இல்:
[P in keyof T]: இது உள்ளீட்டு வகைTஇலிருந்து அனைத்து பண்பு சாவிகள்Pமீது மேப் செய்கிறது.keyof Tஅனைத்து பண்புப் பெயர்களின் யூனியனை வழங்குகிறது.Promise<T[P]>: ஒவ்வொரு கீPக்கும், இது அசல் பண்பின் வகைT[P]ஐ (ஒரு குறியீட்டு அணுகல் வகையைப் பயன்படுத்தி) எடுத்து ஒருPromiseஇல் மூடுகிறது.
சிக்கலான வகை மாற்றங்களை வரையறுக்க keyof மற்றும் குறியீட்டு அணுகல் வகைகள் எவ்வாறு ஒன்றாக செயல்படுகின்றன என்பதற்கான ஒரு சக்திவாய்ந்த demonstrasion இது, ஒத்திசைவற்ற செயல்பாடுகள், தரவு கேச்சிங் அல்லது பண்புகளின் வகையை சீரான முறையில் மாற்ற வேண்டிய எந்தவொரு சூழ்நிலைக்கும் மிகவும் வெளிப்படையான மற்றும் வகை-பாதுகாப்பான API களை உருவாக்க உங்களை அனுமதிக்கிறது. தரவு வடிவங்கள் வெவ்வேறு சேவை எல்லைகளில் மாற்றியமைக்கப்பட வேண்டிய விநியோகிக்கப்பட்ட அமைப்புகள் மற்றும் மைக்ரோசேவைகள் கட்டமைப்புகளில் இத்தகைய வகை மாற்றங்கள் முக்கியமானவை.
முடிவுரை: வகை பாதுகாப்பு மற்றும் நெகிழ்வுத்தன்மையில் தேர்ச்சி பெறுதல்
keyof மற்றும் குறியீட்டு அணுகல் வகைகளைப் பற்றிய நமது ஆழமான ஆய்வு, அவற்றை தனிப்பட்ட அம்சங்களாக மட்டுமல்லாமல், TypeScript இன் மேம்பட்ட பொதுவான அமைப்பின் நிரப்புத் தூண்களாகவும் வெளிப்படுத்துகிறது. அவை உலகெங்கிலும் உள்ள டெவலப்பர்களை நம்பமுடியாத நெகிழ்வான, மறுபயன்பாடு செய்யக்கூடிய மற்றும் மிக முக்கியமாக, வகை-பாதுகாப்பான குறியீட்டை உருவாக்க உதவுகின்றன. சிக்கலான பயன்பாடுகள், பல்வேறு அணிகள் மற்றும் உலகளாவிய ஒத்துழைப்புள்ள ஒரு சகாப்தத்தில், தொகுக்கும்-நேரத்தில் குறியீட்டு தரம் மற்றும் கணிக்கக்கூடிய தன்மையை உறுதி செய்வது மிக முக்கியமானது. இந்த மேம்பட்ட பொதுவான கட்டுப்பாடுகள் அந்த முயற்சியில் அத்தியாவசியமான கருவிகளாகும்.
keyof ஐப் புரிந்துகொண்டு திறம்படப் பயன்படுத்துவதன் மூலம், பண்புப் பெயர்களைத் துல்லியமாக குறிப்பிடவும் கட்டுப்படுத்தவும் நீங்கள் திறனைப் பெறுகிறீர்கள், உங்கள் பொதுவான செயல்பாடுகள் மற்றும் வகைகள் ஒரு பொருளின் செல்லுபடியாகும் பகுதிகளில் மட்டுமே செயல்படுவதை உறுதி செய்கிறது. அதே நேரத்தில், குறியீட்டு அணுகல் வகைகளை (T[K]) தேர்ச்சி பெறுவதன் மூலம், அந்த பண்புகளின் வகைகளை துல்லியமாகப் பிரித்தெடுக்கவும் பெறவும் திறனைத் திறக்கிறீர்கள், உங்கள் வகை வரையறைகளை தழுவல் மற்றும் மிகவும் குறிப்பிட்டதாக மாற்றுகிறது.
getProperty செயல்பாடு மற்றும் MyPick அல்லது MapToPromises போன்ற தனிப்பயன் பயன்பாட்டு வகைகள் போன்ற வடிவங்களில் எடுத்துக்காட்டப்பட்ட keyof மற்றும் குறியீட்டு அணுகல் வகைகளுக்கு இடையிலான ஒத்திசைவு, வகை-மட்ட நிரலாக்கத்தில் ஒரு குறிப்பிடத்தக்க பாய்ச்சலை குறிக்கிறது. இந்த நுட்பங்கள் தரவை வெறுமனே விவரிப்பதற்கு அப்பால் சென்று வகைகளை தீவிரமாக கையாளுவதற்கும் மாற்றுவதற்கும் உங்களை நகர்த்துகின்றன, இது மேலும் வலுவான மென்பொருள் கட்டமைப்புக்கும் பெரிதும் மேம்பட்ட டெவலப்பர் அனுபவத்திற்கும் வழிவகுக்கிறது.
உலகளாவிய டெவலப்பர்களுக்கான செயல்முறை நுண்ணறிவுகள்:
- ஜெனரிக்ஸைத் தழுவுங்கள்: எளிமையான செயல்பாடுகளுக்கு கூட ஜெனரிக்ஸைப் பயன்படுத்தத் தொடங்குங்கள். நீங்கள் அவற்றை எவ்வளவு சீக்கிரம் அறிமுகப்படுத்துகிறீர்களோ, அவ்வளவு இயற்கையாக அவை மாறும்.
- கட்டுப்பாடுகளில் சிந்தியுங்கள்: ஒரு பொதுவான செயல்பாட்டை நீங்கள் எழுதும்போதெல்லாம், உங்களை நீங்களே கேட்டுக்கொள்ளுங்கள்: "இந்த செயல்பாடு செயல்பட
Tக்கு *என்ன* பண்புகள் அல்லது முறைகள் தேவை?" இது இயற்கையாகவேextendsஉட்பிரிவுகள் மற்றும்keyofக்கு உங்களை இட்டுச் செல்லும். - குறியீட்டு அணுகலைப் பயன்படுத்துங்கள்: உங்கள் பொதுவான செயல்பாட்டின் திரும்பும் வகை (அல்லது ஒரு அளவுருவின் வகை) மற்றொரு பொதுவான வகையின் குறிப்பிட்ட பண்பைப் பொறுத்து இருந்தால்,
T[K]ஐப் பற்றி சிந்தியுங்கள். - பயன்பாட்டு வகைகளை ஆராயுங்கள்: TypeScript இன் உள்ளமைக்கப்பட்ட பயன்பாட்டு வகைகளை (
Pick,Omit,Record,Partial,Required) பற்றி நன்கு தெரிந்துகொள்ளுங்கள் மற்றும் அவை இந்த கருத்துக்களை எவ்வாறு பயன்படுத்துகின்றன என்பதைக் கவனியுங்கள். உங்கள் புரிதலை உறுதிப்படுத்த எளிமைப்படுத்தப்பட்ட பதிப்புகளை மீண்டும் உருவாக்க முயற்சிக்கவும். - உங்கள் வகைகளை ஆவணப்படுத்துங்கள்: சிக்கலான பொதுவான வகைகளுக்கு, குறிப்பாக பகிரப்பட்ட நூலகங்களில், அவற்றின் நோக்கம் மற்றும் பொதுவான அளவுருக்கள் எவ்வாறு கட்டுப்படுத்தப்பட்டு பயன்படுத்தப்படுகின்றன என்பதை விளக்கும் தெளிவான கருத்துகளை வழங்கவும். இது சர்வதேச அணி ஒத்துழைப்பிற்கு கணிசமாக உதவுகிறது.
- உண்மையான உலக சூழ்நிலைகளுடன் பயிற்சி செய்யுங்கள்: இந்த கருத்துக்களை உங்கள் அன்றாட குறியீட்டு சவால்களுக்குப் பயன்படுத்துங்கள் – அது ஒரு நெகிழ்வான தரவு கட்டத்தை உருவாக்குவதாக இருந்தாலும், ஒரு வகை-பாதுகாப்பான உள்ளமைவு லோடரை உருவாக்குவதாக இருந்தாலும் அல்லது மறுபயன்பாடு செய்யக்கூடிய API கிளையண்ட்டை வடிவமைப்பதாக இருந்தாலும்.
keyof மற்றும் குறியீட்டு அணுகல் வகைகளுடன் மேம்பட்ட பொதுவான கட்டுப்பாடுகளில் தேர்ச்சி பெறுவது என்பது அதிக TypeScript ஐ எழுதுவது மட்டுமல்ல; இது அனைத்து களங்கள் மற்றும் புவியியல் பகுதிகளிலும் பயன்பாடுகளை நம்பிக்கையுடன் இயக்கும் சிறந்த, பாதுகாப்பான மற்றும் மேலும் பராமரிக்கக்கூடிய குறியீட்டை எழுதுவது பற்றியது. தொடர்ந்து பரிசோதனை செய்யுங்கள், தொடர்ந்து கற்றுக்கொள்ளுங்கள், மற்றும் TypeScript இன் வகை அமைப்பின் முழு சக்தியுடன் உங்கள் உலகளாவிய மேம்பாட்டு முயற்சிகளை மேம்படுத்துங்கள்!